package com.feihong.yw189.bluetooth.utils.djlm.DJLMReader3.reader;

import android.content.Context;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

import com.feihong.yw189.bluetooth.utils.djlm.DJLMReader3.websocket.WebSocket;
import com.feihong.yw189.bluetooth.utils.djlm.DJLMReader3.websocket.WebSocketFactory;
import com.inuker.bluetooth.library.BluetoothClient;
import com.inuker.bluetooth.library.Constants;
import com.inuker.bluetooth.library.connect.listener.BleConnectStatusListener;
import com.inuker.bluetooth.library.connect.options.BleConnectOptions;
import com.inuker.bluetooth.library.connect.response.BleConnectResponse;
import com.inuker.bluetooth.library.connect.response.BleNotifyResponse;
import com.inuker.bluetooth.library.connect.response.BleUnnotifyResponse;
import com.inuker.bluetooth.library.connect.response.BleWriteResponse;
import com.inuker.bluetooth.library.model.BleGattProfile;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.UUID;


/**
 * Created by Sabirjan on 2017/10/12.
 * DJLMReader.
 * 飞宏电子
 * 主要思路：
 * （1）第一步，连接蓝牙设备 ，连接成功开始准备前五条命令
 * （2）第二步 ，连接服务端 (两个端)，连接成功并且前五条命令准备好了，发给服务端
 * （3）第三步，服务端返回 内部验证数据，.....
 * (4)
 */

public class NewDJLMReader2 {
    private static final String TAG = "蓝牙";
    private static final UUID RX_SERVICE_UUID = UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb");
    private static final UUID TX_CHAR_UUID = UUID.fromString("0000fff4-0000-1000-8000-00805f9b34fb");
    private static final UUID RX_CHAR6_UUID = UUID.fromString("0000fff6-0000-1000-8000-00805f9b34fb");
    private static final UUID RX_CHAR7_UUID = UUID.fromString("0000fff7-0000-1000-8000-00805f9b34fb");

    private static final String OUT_OK_MESSAGE = "{\"A\":\"OUT_WAIT\",\"C\":[\"9000\"]}";
    private static final int OVER_MAX_COUNT = 10;
    private static final int STEP1 = 1;
    private static final int STEP2 = 2;
    private static final int STEP3 = 3;
    private static final int STEP4 = 4;
    private static final int STEP5 = 5;
    private static final int STEP_VERTION = 1000;
    HandlerThread handlerThread = null;
    TransHandler transHandler = null;
    //内部验证的集合
    //步骤3 和步骤 4
    StringBuffer sb_in = new StringBuffer();
    ArrayList<String> bleCommands = new ArrayList<>();
    int bleCommandindex = 0;
    int bleCommandSize = 0;
    Message message;

    private int READ_DATA_TYPE = 2;//读文件数据类型，1 表示一个一个发送，2 表示一次性发送

    BleWriteResponse mBleWriteResponse = new BleWriteResponse() {
        @Override
        public void onResponse(int code) {
            Log.e(TAG, "写入状态回调: code = " + code);
            if (code == Constants.REQUEST_SUCCESS) {
                //  mHandler.sendEmptyMessage(ErrorCode.ERROR_CODE1);
            } else {
                if (currenStep != STEP1) {
                    destroy();
                    mHandler.sendEmptyMessage(ErrorCode.ERROR_CODE14);
                } else {
                    neibuyanzhengStep = 0;
                    //step1();
                    currenStep = STEP1;
                    // step1();//开始给蓝牙设备发送消息
                    transHandler.sendEmptyMessageDelayed(101, 1000);
                }
            }
        }
    };
    BleUnnotifyResponse mBleUnnotifyResponse = new BleUnnotifyResponse() {
        @Override
        public void onResponse(int code) {

        }
    };
    private String strErrorInfo;
    private Context mContext;
    private BluetoothClient mBluetooth;
    private String mHost = "";
    private String mHost2 = "";
    private String mMacAddress = "";
    private ArrayList<String> commandList = new ArrayList<>();
    protected boolean isSuccess = false;//是否读卡成功
    private boolean isDon = false;//是否已完成
    private DJLM3CallBack callBack;//回调
    private int overCount = 0;// 不放身份证 ，重试次数。一般 10次后就提示读卡失败
    private int currenStep = STEP_VERTION;//当前正在执行的步骤
    private WebSocket transwebSocket = null;
    private String bleVersion = "";//读卡器设备版本号
    private String transWS = "";//trans 通道webSocket连接
    private String bmpServer = "";// 图片解码通道连接
    private boolean initSuccess = false;
    private int neibuyanzhengStep = 0;//前五条命令的下标
    private ArrayList<String> neibuyanzhengBleDatas = new ArrayList<>();//保存前五条内部验证的命令
    private ArrayList<String> cardDatas = new ArrayList<>();
    private long startTime = 0;
    private long lanyaTime = 0;
    protected Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            transHandler.removeMessages(100);
            if (isDon && !isSuccess) {
                return;
            }
            isDon = true;
            if (msg.what == 200) {
                closeAll();
                return;
            }
            if (msg.what > 0) {
                //错误
                strErrorInfo = ErrorCode.getErrorMessage(msg.what);
                if (msg.obj == null)
                    callBack.error(msg.what, ErrorCode.getErrorMessage(msg.what));
                else
                    callBack.error(msg.what, msg.obj.toString());
            } else if (msg.what == 0) {
                if (msg.obj != null) {
                    CardInfo carinfo = (CardInfo) msg.obj;
                    Log.e(TAG, "handleMessage: " + carinfo.toString());
                    isSuccess = true;
                    callBack.success(carinfo);
                    strErrorInfo = "OK";
                } else {
                    strErrorInfo = ErrorCode.getErrorMessage(ErrorCode.ERROR_CODE5);
                    callBack.error(ErrorCode.ERROR_CODE5, ErrorCode.getErrorMessage(ErrorCode.ERROR_CODE5));
                }
            }

            closeAll();

        }
    };
    //蓝牙返回的数据通知
    BleNotifyResponse mBleNotifyResponse = new BleNotifyResponse() {
        @Override
        public void onNotify(UUID service, UUID character, byte[] value) {

            if (currenStep == STEP_VERTION) {
                if (value != null) {
                    bleVersion = "V" + value[1] + "." + value[2] + value[3] + value[4];
                    Log.e(TAG, "doBle: 设备版本:" + bleVersion);
                }
                currenStep = STEP1;
                neibuyanzhengStep = 0;
                // step1();//开始给蓝牙设备发送消息
                transHandler.sendEmptyMessageDelayed(101, 0);
                return;
            }
            String result = HexUtil.bytesToHexString(value);
            Log.e(TAG, "读取状态: value = " + result + "   index:" + neibuyanzhengStep);
            doBle(result);
        }

        @Override
        public void onResponse(int code) {
            Log.e(TAG, "读取状态: code = " + code);
        }
    };

    public NewDJLMReader2(Context context, String host1, String host2, DJLM3CallBack callBack) throws Exception {
        mContext = context;
        mHost = host1;
        mHost2 = host2;
        if (callBack == null) {
            throw new Exception("回调不能为NULL");
        }
        this.callBack = callBack;
        //  init();
        handlerThread = new HandlerThread("handler_hread");
        handlerThread.start();
        transHandler = new TransHandler(handlerThread.getLooper());

    }

    protected void destroy() {
        try {
            if (mBluetooth != null) {
                mBluetooth.refreshCache(mMacAddress);
                mBluetooth.disconnect(mMacAddress);
            }
            if (transwebSocket != null && transwebSocket.isOpen()) {
                transwebSocket.disconnect(1001, "1");
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 关闭所有连接
     */
    protected void closeAll() {
        try {


            if (mBluetooth != null && transwebSocket != null)
                Log.e(TAG, "closeAll: 开始释放连接.....isOpen=" + transwebSocket.isOpen() + " 蓝牙:" + mBluetooth.getConnectStatus(mMacAddress));

            if (mBluetooth != null) {
                mBluetooth.unnotify(mMacAddress, RX_SERVICE_UUID, TX_CHAR_UUID, mBleUnnotifyResponse);
                mBluetooth.clearRequest(mMacAddress, Constants.REQUEST_WRITE);
                mBluetooth.clearRequest(mMacAddress, Constants.REQUEST_READ);
                mBluetooth.disconnect(mMacAddress);
                mBluetooth.disconnect(mMacAddress);
            }
            if (transwebSocket != null) {
                transwebSocket.clearListeners();
                transwebSocket.disconnect(1001, "1");
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        if (isSuccess) {
            destroy();
        }
        if (commandList != null) {
            commandList.clear();
            commandList = null;
        }
        if (cardDatas != null) {
            cardDatas.clear();
            cardDatas = null;
        }
        neibuyanzhengBleDatas = null;
    }

    public void read(String macAddress) {
        transHandler.removeMessages(100);

        mMacAddress = macAddress;
        isSuccess = false;
        closeAll();
        init();
        //第一步
        if (initSuccess) {
            transHandler.sendEmptyMessageDelayed(100, 20000);//设置一个定时器，如果20秒内读卡没有完成，则提示读卡超时
            new Thread(new Runnable() {
                @Override
                public void run() {
                    beginConntentBle();
                }
            }).start();
        } else {
            mHandler.sendEmptyMessage(ErrorCode.ERROR_CODE11);
        }
    }


    private void init() {
        initSuccess = false;
        isSuccess = false;
        isFristMessage = false;
        isDon = false;
        transwebSocket = null;
        //  new BleDeviceTools().createBond(BluetoothUtils.getRemoteDevice(mMacAddress));
        transWS = "";
        cardDatas = new ArrayList<>();
        overCount = 0;
        neibuyanzhengStep = 0;
        currenStep = 1;
        neibuyanzhengBleDatas = new ArrayList<>();
        //初始化命令
        commandList = CommandTools.getCommandList();
        try {
            mBluetooth = new BluetoothClient(mContext);
            mBluetooth.stopSearch();
            //第一步 ，蓝牙连接
            initSuccess = true;
        } catch (Exception ex) {
            ex.printStackTrace();
            mHandler.sendEmptyMessage(ErrorCode.ERROR_CODE1);
        }
    }

    //第一步，连接蓝牙设备.
    private void beginConntentBle() {
        BleConnectOptions options = new BleConnectOptions.Builder()
                .setConnectRetry(3)   // 连接如果失败重试3次
                .setConnectTimeout(5000)   // 连接超时15s
                .setServiceDiscoverRetry(3)  // 发现服务如果失败重试3次
                .setServiceDiscoverTimeout(5000)  // 发现服务超时2s
                .build();

        mBluetooth.connect(mMacAddress, options, new BleConnectResponse() {
            @Override
            public void onResponse(int code, BleGattProfile data) {
                Log.e(TAG, "蓝牙连接: " + code);
                if (code == Constants.REQUEST_SUCCESS) {
                    // writeBle2("0C0101");//高速模式
                    //成功连接
                    mBluetooth.unnotify(mMacAddress, RX_SERVICE_UUID, TX_CHAR_UUID, mBleUnnotifyResponse);
                    //注册通知
                    mBluetooth.notify(mMacAddress, RX_SERVICE_UUID, TX_CHAR_UUID, mBleNotifyResponse);
                    //先获取读卡器版本号，获取成功后进入第一步骤
                    currenStep = STEP_VERTION;
                    //writeBle2("0B0131");//获取设备版本的命令
                    sendVerstionCommand();
                    startTime = System.currentTimeMillis();
                    //
                } else {
                    if (callBack != null) {
                        Log.e(TAG, "无法初始化蓝牙服务！");
                        mBluetooth.unregisterConnectStatusListener(mMacAddress, mBleConnectStatusListener);
                        mHandler.sendEmptyMessage(ErrorCode.ERROR_CODE1);
                        mBluetooth.refreshCache(mMacAddress);
                        mBluetooth.disconnect(mMacAddress);
                        mBluetooth.disconnect(mMacAddress);
                    }
                }
            }
        });
    }

    private BleConnectStatusListener mBleConnectStatusListener = new BleConnectStatusListener() {
        @Override
        public void onConnectStatusChanged(String mac, int status) {
            if (status == Constants.STATUS_DISCONNECTED) {
                if (!isDon) {
                    mHandler.sendEmptyMessage(ErrorCode.ERROR_CODE1);
                }
            }
        }
    };

    //第一步，开始给蓝牙设备发送消息。
    private void step1() {


        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    if (currenStep == STEP1) {
                        overCount++;
                        if (overCount > OVER_MAX_COUNT) {
                            // 多次重新发送给蓝牙设备，如果一直没有返回值，说明没有正确的放入身份证。
                            mHandler.sendEmptyMessage(ErrorCode.ERROR_CODE12);
                            return;
                        }
                        neibuyanzhengBleDatas = new ArrayList<>();
                        int i = 0;
                        neibuyanzhengStep = 0;
                        Log.i(TAG, "run: 开始重新发送第一步的命令集....");

                        writeBle(CommandTools.SeriesOfCommandsFromSelectToAuthen[neibuyanzhengStep]);
                        /*
                        while (i < CommandTools.SeriesOfCommandsFromSelectToAuthen.length) {
                            writeBle(CommandTools.SeriesOfCommandsFromSelectToAuthen[i]);
                            try{
                              //  Thread.sleep(50);
                            }
                            catch (Exception ex){}
                            i++;
                        }
                        */
                    }
                } catch (Exception ex) {
                    mHandler.sendEmptyMessage(ErrorCode.ERROR_CODE14);
                }
            }
        }).start();
    }

    private void writeBle(String msg) {
        byte[] query = HexUtil.hexStringToBytes(msg);
        byte[] newValue = new byte[query.length + 1];
        newValue[0] = 23;
        System.arraycopy(query, 0, newValue, 1, query.length);
        Log.e(TAG, "writeBle: 发送的命令:" + HexUtil.bytesToHexString(newValue));

        mBluetooth.writeNoRsp(mMacAddress, RX_SERVICE_UUID, RX_CHAR6_UUID, newValue, mBleWriteResponse);
        /*
        byte[] query = HexUtil.hexStringToBytes(msg);
        mBluetooth.writeNoRsp(mMacAddress, RX_SERVICE_UUID, RX_CHAR6_UUID, query, mBleWriteResponse);
        */
    }
    private void sendBeep() {

        byte[] query = HexUtil.hexStringToBytes("0A0131");
        mBluetooth.write(mMacAddress, RX_SERVICE_UUID, RX_CHAR7_UUID, query, mBleWriteResponse);
    }
    private void sendVerstionCommand() {

        byte[] query = HexUtil.hexStringToBytes("0B0131");
        mBluetooth.write(mMacAddress, RX_SERVICE_UUID, RX_CHAR7_UUID, query, mBleWriteResponse);
    }

    private void writeBle2(String msg) {
        Log.e(TAG, "writeBle2: 发送的命令:" + msg);
        byte[] query = HexUtil.hexStringToBytes(msg);
        mBluetooth.write(mMacAddress, RX_SERVICE_UUID, RX_CHAR6_UUID, query, mBleWriteResponse);
        /*
        byte[] query = HexUtil.hexStringToBytes(msg);
        byte[] newValue = new byte[query.length + 1];
        newValue[0] = 23;
        System.arraycopy(query, 0, newValue, 1, query.length);
        Log.e(TAG, "writeBle: 发送的命令:"+HexUtil.bytesToHexString(newValue));
        mBluetooth.writeNoRsp(mMacAddress, RX_SERVICE_UUID, RX_CHAR6_UUID, newValue, mBleWriteResponse);
        */
    }

    public void setHost(String newHost,String newHost2) {
        if (!TextUtils.isEmpty(newHost)&&!TextUtils.isEmpty(newHost2)) {
            mHost = newHost;
            mHost2 = newHost2;
        }
    }

    //步骤2  ，成功读取 前五条数据后连接服务端，申请通道
    private void step2() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                initWebSoket();
            }
        }).start();
    }

    /**
     * 连接服务端
     */
    private void initWebSoket() {
        transWS = "ws://" + mHost2 + "/djlmwebsocket";
        bmpServer = "http://" + mHost + "/MutexComm/bmp_decrypt";
        try {
            String json = getDNCode();
            WebSocketFactory factory = new WebSocketFactory().setConnectionTimeout(5000);
            factory.setVerifyHostname(false);
            transwebSocket = factory.createSocket(transWS);
            transwebSocket.addHeader("DN", json.replace("\n", ""));
            transwebSocket.addListener(new DJLMWebSocketListener(this));
            transwebSocket.setAutoFlush(true);
            transwebSocket.setExtended(true);
            transwebSocket.setPongInterval(100);
            transwebSocket.setPingInterval(100);
            transwebSocket.setMissingCloseFrameAllowed(true);
            transwebSocket.setMaxPayloadSize(0);
            transwebSocket.connect();
        } catch (Exception ex) {
            mHandler.sendEmptyMessage(ErrorCode.ERROR_CODE2);
            ex.printStackTrace();
        }
    }

    /**
     * 获取前五条命令JSON
     *
     * @return
     */
    private String getDNCode() {
        StringBuffer sb = new StringBuffer();
        sb.append("[");
        int lastIndex = neibuyanzhengBleDatas.size() - 1;
        for (int i = 0; i < neibuyanzhengBleDatas.size(); i++) {
            sb.append("\"");
            sb.append(neibuyanzhengBleDatas.get(i));
            if (i < lastIndex) {
                sb.append("\",");
            } else {
                sb.append("\"]");
            }
        }
        return sb.toString();
    }

    /**
     * 处理Ble返回的数据
     *
     * @param result
     */
    private void doBle(String result) {
        if (isDon)
            return;
        if ("0000".equals(result)) {
            Log.e(TAG, "onNotify: 高低速切换....");
            return;
        }
        if (TextUtils.isEmpty(result) && currenStep == STEP1) {
            //没有数据，可能是没有放好身份证，或者无法读取
            neibuyanzhengStep = 0;
            // step1();
            transHandler.sendEmptyMessageDelayed(101, 500);
            return;
        }
        if (currenStep == STEP1) {
            Log.e(TAG, "正在采集第一步....");
            neibuyanzhengBleDatas.add(result);
            neibuyanzhengStep++;
            if (neibuyanzhengBleDatas.size() == 5) {
                //准备好了
                Log.e(TAG, "onNotify: 已经准备好了......");
                currenStep = STEP2;
                step2();
            } else if (neibuyanzhengStep <= 4) {
                writeBle(CommandTools.SeriesOfCommandsFromSelectToAuthen[neibuyanzhengStep]);
            } else {
                neibuyanzhengStep = 0;
                // step1();
                transHandler.sendEmptyMessageDelayed(101, 500);
            }

            return;
        }
        //內部验证
        if (currenStep == STEP3) {
            //内部验证已完成。步骤3 总有2条命令  。
            // 整个读卡过程中，步骤3 执行2次。第一次读身份证数据，第二次服务端解码身份证数据
            //第一次 步骤3 总执行2个蓝牙命令 内部验证和身份证随机码（服务端外部认证）
            //第二次只执行 内部验证的命令
            Log.e(TAG, "doWebSocket: 内部验证接受时间:" + System.currentTimeMillis() + "  bleCommandindex=" + bleCommandindex);
            sb_in = new StringBuffer();
            sb_in.append("{\"A\":\"IN_WAIT\",\"C\":[");
            sb_in.append("\"" + result + "\"");
            sb_in.append("]}");
            writeTrans(sb_in.toString());
            bleCommandindex++;

        } else if (currenStep == STEP4) {

            Log.i(TAG, "doBle: 正在开始运行步骤5.。。。。");
            //外部认证已完成，如果身份证数据没有获取，先获取身份证数据。如果已经获取完毕，直接发给服务端
            //整个读卡过程中，外部认证只执行一次（没有出现错误情况下）
            if (cardDatas == null || cardDatas.size() < 97) {
                Log.i(TAG, "doBle:外部认证已完成，如果身份证数据没有获取");
                runStep5();
            } else {
                //已经获取了文件数据，不需要重新获取
                Log.i(TAG, "doBle:已经获取了文件数据，不需要重新获取");
                currenStep = STEP5;
                bleCommandSize = commandList.size();
                checkIsReady();
            }
            return;
        } else if (currenStep == STEP5) {

            Log.e("文件数据", "收到身份证文件数据: " + result + "  时间:" + System.currentTimeMillis());
            if (READ_DATA_TYPE == 1) {
                bleCommandindex++;
                if (bleCommandindex == 15) {
                    result = "0100040000009000";//身份证文件数据部分的第十五个命令是代表 有没有指纹信息。
                    //因为店家联盟阅读器暂时不需要指纹信息部分，所以发给服务端的是没有指纹的数据
                    //这样不需要执行指纹部分的命令。总命令减少到97个
                }
                Log.e(TAG, "doBle: bleCommandindex=" + bleCommandindex + " result= " + result);
                //writeTrans(result);
                if (result != null && result.length() >= 4) {
                    //为了减少网络传输数据的大小，每个命令后面的9000去掉了
                    cardDatas.add(result.substring(0, result.length() - 4));
                } else
                    cardDatas.add("");
                checkIsReady();

            } else {
                bleCommandindex++;
                if (bleCommandindex == 1 || bleCommandindex == 16 || bleCommandindex == 33) {
                    cardDatas.add("");
                    bleCommandindex++;
                }
                int len = 32;//Default Len 默认一个数据的长度
                Log.e(TAG, "doBle: 默认长度:" + len + " 当前长度:" + result.length());
                if (result.length() > len) {
                    if (result.length() % len == 0) {
                        int itemCount = result.length() / len;
                        for (int i = 0; i < itemCount; i++) {
                            int index = len * i;
                            String temp = result.substring(index, index + len);
                            Log.e(TAG, "doBle:处理了一个合并:" + temp + "  index=" + index);
                            cardDatas.add(temp);
                            if (i != (itemCount - 1))
                                bleCommandindex++;
                        }
                    } else {
                        //可能 010004000000 合并了
                        if (result.startsWith("010004")) {
                            cardDatas.add("010004000000");
                            bleCommandindex++;
                            String temp = result.substring(12, 12 + len);
                            cardDatas.add(temp);
                        } else {
                            String temp = result.substring(0, len);
                            cardDatas.add(temp);
                            bleCommandindex++;
                            cardDatas.add("010004000000");
                        }
                    }
                } else {
                    if (bleCommandindex == 15) {
                        // result = "0100040000009000";//身份证文件数据部分的第十五个命令是代表 有没有指纹信息。
                        result = "010004000000";//身份证文件数据部分的第十五个命令是代表 有没有指纹信息。
                        //因为店家联盟阅读器暂时不需要指纹信息部分，所以发给服务端的是没有指纹的数据
                        //这样不需要执行指纹部分的命令。总命令减少到97个
                    }
                    //         Log.e(TAG, "doBle: bleCommandindex=" + bleCommandindex + " result= " + result);
                    //writeTrans(result);
                    if (result != null && result.length() >= 4) {
                        //为了减少网络传输数据的大小，每个命令后面的9000去掉了
                        //  cardDatas.add(result.substring(0, result.length() - 4));
                        cardDatas.add(result);
                    }
                }
                checkIsReady();
            }
        }
    }

    /**
     * 检测身份证文件数据是否读取完毕，如果读取完毕发给服务端
     */
    private void checkIsReady() {

        if (cardDatas.size() == bleCommandSize) {
            String json = createCodesJSON("DATA_TRANS", cardDatas);
            writeTrans(json);

        }
        if (READ_DATA_TYPE == 2) {
            if (bleCommandindex == 15) {
                Log.e("文件数据", "发出去第二条命令:54006012010010");
                writeBle2("54006012010010");//发送第二个文件
            } else if (bleCommandindex == 32) {
                Log.e("文件数据", "发出去第三条命令:54006013040010");
                writeBle2("54006013040010");//发送第三个文件
            }
        }
    }

    byte[] b;
    private boolean isFristMessage = false;

    /**
     * 读取身份证数据成功时被调用。
     *
     * @param data
     */
    protected void success(byte[] data) {
        isSuccess = true;
        b = data;
        sendBeep();
        mHandler.sendEmptyMessageDelayed(200,200);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    ParseCardBaseInfo parser = new ParseCardBaseInfo();
                    CardInfo cardInfo = parser.GetInfo(b);
                    cardInfo.bitmap_pic = parser.parseBitmap(bmpServer, mMacAddress, b);
                    if (cardInfo.bitmap_pic == null) {
                        Message message = new Message();
                        message.what = ErrorCode.ERROR_CODE4;
                        message.obj = ErrorCode.getErrorMessage(ErrorCode.ERROR_CODE4);
                        b = null;
                        mHandler.sendMessage(message);
                        return;
                    }
                    Message message = new Message();
                    message.what = 0;
                    message.obj = cardInfo;
                    b = null;
                    mHandler.sendMessage(message);
                } catch (Exception ex) {
                    ex.printStackTrace();
                    Message message = new Message();
                    message.what = ErrorCode.ERROR_CODE6;
                    message.obj = ErrorCode.getErrorMessage(ErrorCode.ERROR_CODE6);
                    b = null;
                    mHandler.sendMessage(message);
                }
            }
        }).start();
    }

    /**
     * 处理WebSocket返回的数据
     *
     * @param message
     */
    protected void doWebSocket(String message) {
        if (isDon)
            return;
        if (TextUtils.isEmpty(message)) {
            Log.e(TAG, "doWebSocket: 收到空字符....");
            return;
        }
        try {
            JSONObject object = new JSONObject(message);
            if ("IN".equals(object.optString("A"))) {//做内部验证
                //收到内部验证的数据
                //if (currenStep == STEP3) return;
                if (!isFristMessage) {
                    isFristMessage = true;
                }
                Log.e(TAG, "doWebSocket: 收到内部验证的数据:" + message);
                currenStep = STEP3;
                bleCommands = new ArrayList<>();
                sb_in = new StringBuffer();
                bleCommandindex = 0;
                JSONArray array = object.getJSONArray("C");
                if (cardDatas == null || cardDatas.size() == 0)
                    array.put("0084000008");//获取身份证随机码

                // Log.e(TAG, "doWebSocket: 内部验证发送时间:" + System.currentTimeMillis());
                bleCommandSize = array.length();
                for (int i = 0; i < bleCommandSize; i++) {
                    writeBle(array.getString(i));
                }
            } else if ("OUT".equals(object.optString("A"))) {//做外部验证
                Log.e(TAG, "doWebSocket: 收到外部验证的数据:" + message);
                //  if (currenStep == STEP4) return;
                currenStep = STEP4;
                writeTrans(OUT_OK_MESSAGE);
                bleCommands = new ArrayList<>();
                sb_in = new StringBuffer();
                bleCommandindex = 0;
                JSONArray array = object.getJSONArray("C");
                //    array.put("00A40000026011");
                bleCommandSize = array.length();
                for (int i = 0; i < bleCommandSize; i++) {
                    writeBle(array.getString(i));
                }
            } else if ("DATA_TRANS".equals(object.optString("A"))) {
                //服务端虽然传过来获取文件数据部分的命令
                //但是我们在客户端里面外部认证做完了就不等服务端的数据，直接开始读身份证数据了

            } else if ("result".equals(object.optString("A"))) {
                //读卡结果 （读卡错误情况下被调用）
                doReaderPort(object.getString("C"));
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 发给Ble设备所有的身份证文件数据部分的命令
     */
    private void runStep5() {

        Log.i(TAG, "runStep5: 正在发送身份证文件数据////");
        currenStep = STEP5;
        cardReadTimeStart = System.currentTimeMillis();
        bleCommandindex = 0;
        Log.i(TAG, "runStep5: 正在发送身份证文件数据1////");
        cardDatas = new ArrayList<>();
        int i = 0;
        bleCommandSize = commandList.size();
        Log.i(TAG, "runStep5: 正在发送身份证文件数据2////");
        if (READ_DATA_TYPE == 1) {
            Log.i(TAG, "runStep5:-----READ_DATA_TYPE");
            while (i < bleCommandSize) {
                writeBle(commandList.get(i));
                ++i;
            }
        } else {
            Log.i(TAG, "runStep5:-----1");
            Log.e("蓝牙", "发出去第一条命令:5400601100D610");
            writeBle2("5400601100D610");
            Log.i(TAG, "runStep5:-----2");
        }
    }

    long cardReadTimeStart = 0;

    /**
     * 创建返回服务端的命令JSON
     *
     * @param action
     * @param commands
     * @return
     */
    private String createCodesJSON(String action, ArrayList<String> commands) {
        StringBuffer sb = new StringBuffer();
        sb.append("{\"A\":\"" + action + "\",");
        sb.append("\"C\":[");
        for (int i = 0, len = commands.size(); i < len; i++) {
            String command = commands.get(i).replace("\n", "");
            command = command.replace("f ", "");
            command = command.replace("\n", "");
            if (i != len - 1)
                sb.append("\"" + command + "\",");
            else
                sb.append("\"" + command + "\"");
        }
        sb.append("]}");

        return sb.toString();
    }

    /**
     * 内容发给服务端
     *
     * @param input
     */
    private void writeTrans(String input) {
        Log.e(TAG, "writeTrans: " + input);
        message = new Message();
        message.obj = input;
        message.what = 1;
        transHandler.sendMessage(message);
    }

    /**
     * 处理服务端返回的错误信息
     *
     * @param result
     */
    private void doReaderPort(String result) {
        if (result == null) {
            mHandler.sendEmptyMessage(ErrorCode.ERROR_CODE5);
            return;
        }
        if (result.length() > 20) {
            String temp = result.substring(14, 14 + 6);
            Log.e(TAG, "onMessage: TEMP=" + temp);
            Log.e(TAG, "onMessage: LEN=" + result);
            String strName = ErrorCode.getMessage(temp);
            Log.e(TAG, "doReaderPort: 错误信息:" + strName);
            //读卡失败
            Message message = new Message();
            message.obj = strName;
            message.what = ErrorCode.ERROR_CODE5;
            mHandler.sendMessage(message);
            return;
        } else {
            mHandler.sendEmptyMessage(ErrorCode.ERROR_CODE5);
            return;
        }
    }

    class TransHandler extends Handler {

        public TransHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1) {
                transwebSocket.sendText(msg.obj.toString());
                //   transwebSocket.sendBinary(msg.obj.toString().getBytes());
                transwebSocket.flush();
            } else if (msg.what == 2) {
                byte[] query = HexUtil.hexStringToBytes(msg.obj.toString().trim());
                mBluetooth.writeNoRsp(mMacAddress, RX_SERVICE_UUID, RX_CHAR6_UUID, query, mBleWriteResponse);

            } else if (msg.what == 101 && currenStep == STEP1) {
                step1();
            } else if (msg.what == 100) {
                if (!isDon) {
                    mHandler.sendEmptyMessage(ErrorCode.ERROR_CODE13);
                }
            }
        }
    }

}
